package com.lcxw.hxzbapi.controller.giftandcubecontroller;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.lcxw.hxzbapi.controller.roomcontroller.RoomRealization;
import com.lcxw.hxzbapi.entity.pojo.Cube;
import com.lcxw.hxzbapi.entity.pojo.CubeDrawRange;
import com.lcxw.hxzbapi.entity.pojo.CubeDrawRecord;
import com.lcxw.hxzbapi.entity.pojo.CubeResult;
import com.lcxw.hxzbapi.entity.pojo.Gift;
import com.lcxw.hxzbapi.entity.pojo.YwpdGiftBag;
import com.lcxw.hxzbapi.entity.requestBean.GetMyDrawRecordReq;
import com.lcxw.hxzbapi.entity.requestBean.RequestParamBasic;
import com.lcxw.hxzbapi.entity.response.BaodengGiftInfo;
import com.lcxw.hxzbapi.entity.response.CubeDrawRecordForMem;
import com.lcxw.hxzbapi.entity.response.MyDrawRecordResp;
import com.lcxw.hxzbapi.entity.response.Response;
import com.lcxw.hxzbapi.service.*;
import com.lcxw.hxzbapi.tencentim.common.ImCommand;
import com.lcxw.hxzbcommon.common.RedisUtils;
import com.lcxw.hxzbcommon.common.RoomUtils;
import com.lcxw.hxzbcommon.common.StringUtil;
import com.lcxw.hxzbcommon.entity.ErrorCode;
import java.util.ArrayList;
import java.util.List;
import java.util.Objects;
import java.util.Random;
import javax.annotation.Resource;
import lombok.SneakyThrows;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;

/**
 * 魔方的实现类
 */

@Component
@Slf4j
public class CubeRealization {

    @Resource
    CubeService cubeService;

    @Resource
    GiftBagService giftBagService;

    @Resource
    CubeDrawRecordService cubeDrawRecordService;

    @Resource
    RedisUtils redisUtils;

    @Resource
    RoomRealization roomRealization;

    @Resource
    GiftService giftService;

    @Resource
    YwpdRoomService ywpdRoomService;

    public List<CubeResult> luckyDraw(long userId, long roomId, String type, int times)
        throws Exception {
        //获取魔方
        List<Cube> cubes = cubeService.selectByType(type);
        int cubesSize = cubes.size();
        int baodengCountDown = 0;

        if (type.equals("luckyCube")) {
            //判断该房间是否在爆灯状态下，如果在爆灯状态下，则需要将极品的抽奖概率 翻3倍
            String baodeng_countDown_redisKey = RoomUtils.get_baodeng_countDown_redisKey(RoomUtils.get_roomLuckyCubePublic_key());
            if (null != redisUtils.string_get(baodeng_countDown_redisKey)) {
                baodengCountDown = Integer
                    .parseInt(redisUtils.string_get(baodeng_countDown_redisKey));
            }
        } else if (type.equals("diamondCube")) {
            //判断该房间是否在爆灯状态下，如果在爆灯状态下，则需要将极品的抽奖概率 翻3倍
            String diamondBaodeng_countDown_redisKey = RoomUtils
                .get_diamondBaodeng_countDown_redisKey(RoomUtils.get_roomDiamondCubePublic_key());

            if (null != redisUtils.string_get(diamondBaodeng_countDown_redisKey)) {
                baodengCountDown = Integer
                    .parseInt(redisUtils.string_get(diamondBaodeng_countDown_redisKey));
            }
        }

        //如果爆灯剩余时间大于0，则将爆灯礼物的中奖率翻3倍
        if (baodengCountDown > 0) {
            for (int i = 0; i < cubesSize; i++) {
                if (1 == cubes.get(i).getIsBaodeng()) {
                    Cube cube = cubes.get(i);
                    cube.setOdds(cube.getOdds() * 1);//爆灯倍率
                    cubes.remove(cubes.get(i));
                    cubes.add(i, cube);
                }
            }
        }

        //抽奖环节
        List<CubeResult> cubeResultList = new ArrayList<>();
        for (int i = 0; i < times; i++) {

            int prizeIndex = getPrizeIndex(cubes);
            Cube cube = cubes.get(prizeIndex);
            CubeResult cubeResult = new CubeResult();
            cubeResult.setPrizeIndex(prizeIndex);
            cubeResult.setNum(1);
            cubeResult.setCube(cube);

            cubeResultList.add(cubeResult);
        }
        if (type.equals("luckyCube")) {
            int baodengValue = roomRealization.updateBaodengValue(RoomUtils.get_roomLuckyCubePublic_key(), times);
            if (baodengValue >= 400) {
                roomRealization.initBaodeng(RoomUtils.get_roomLuckyCubePublic_key());
                roomRealization.startBaodeng(RoomUtils.get_roomLuckyCubePublic_key());
                baodengValue = 0;
            }
            //通知所有正在聊天的聊天室
            roomRealization.luckyCubeChange(null, baodengValue);
        } else if (type.equals("diamondCube")) {
            int baodengValue = roomRealization.updateDiamondBaodengValue(RoomUtils.get_roomDiamondCubePublic_key(), times);
            if (baodengValue >= 200) {
                roomRealization.initDiamondBaodeng(RoomUtils.get_roomDiamondCubePublic_key());
                roomRealization.startDiamondBaodeng(RoomUtils.get_roomDiamondCubePublic_key());
                baodengValue = 0;
            }
            roomRealization.diamondCubeChange(null, baodengValue);
        }

        log.info("用户 {} 抽奖 {} 次完成。", userId, times);
        return cubeResultList;
    }

    public void updateGiftBag(long userId, List<CubeResult> cubeResultList) {

        for (CubeResult cubeResult : cubeResultList
        ) {
            int giftId = cubeResult.getCube().getGiftId();
            int cubeNum = cubeResult.getNum();
            if (null == giftBagService.selectByUserIdAndGiftId(userId, giftId)) {
                YwpdGiftBag ywpdGiftBag = new YwpdGiftBag();
                ywpdGiftBag.setGiftId(giftId);
                ywpdGiftBag.setGiftNum(cubeNum);
                ywpdGiftBag.setUserId(userId);
                ywpdGiftBag.setAddTime(StringUtil.getDateTime());
                giftBagService.insert(ywpdGiftBag);
            } else {
                giftBagService.updateGiftNum(userId, giftId, cubeNum);
            }
        }

    }

    //在抽奖记录里添加新抽奖记录
    public void addCubeDrawRecord(long userId, List<CubeResult> cubeResultList, String type,
        int times) {
        String drawTYpe = type.equals("luckyCube") ? "幸运魔方" : "钻石魔方";

        switch (times) {
            case 1:
                drawTYpe += "一次游玩";
                break;
            case 10:
                drawTYpe += "十次游玩";
                break;
            case 100:
                drawTYpe += "百次游玩";
                break;
        }
        String addTime=StringUtil.getDateTime();
        for (CubeResult cubeResult : cubeResultList
        ) {
            int giftId = cubeResult.getCube().getGiftId();
            int cubeNum = cubeResult.getNum();
            CubeDrawRecord cubeDrawRecord = new CubeDrawRecord();
            cubeDrawRecord.setUserId(userId);
            cubeDrawRecord.setGiftId(giftId);
            cubeDrawRecord.setGiftNum(cubeNum);
            cubeDrawRecord.setDrawType(drawTYpe);
            cubeDrawRecord.setAddTime(addTime);
            cubeDrawRecordService.insert(cubeDrawRecord);
        }
    }

    //获取我的中奖记录
    public Response getMyDrawRecord(GetMyDrawRecordReq requestBody) throws Exception {
        long userId = Long.parseLong(requestBody.getUserId());
        Integer pageNum = requestBody.getPageNum();
        Integer pageSize = requestBody.getPageSize();
        if (pageSize == null) {
            pageSize = 10;
        }
        List<CubeDrawRecord> cubeDrawRecords = cubeDrawRecordService
            .selectByUserId(userId, pageNum, pageSize);
        List<MyDrawRecordResp> drawRecordList = new ArrayList<>();
        for(CubeDrawRecord  recordForMem:cubeDrawRecords){
            MyDrawRecordResp myDrawRecordResp = new MyDrawRecordResp();
            List<CubeDrawRecordForMem> records=cubeDrawRecordService.getLists(recordForMem.getAddTime(),recordForMem.getUserId()+"");
            myDrawRecordResp.setAddTime(recordForMem.getAddTime());
            myDrawRecordResp.setDrawType(recordForMem.getDrawType());
            myDrawRecordResp.setGifts(records);
            drawRecordList.add(myDrawRecordResp);
        }
        /*List<MyDrawRecordResp> drawRecordList = new ArrayList<>();
        for (CubeDrawRecord cubeDrawRecord : cubeDrawRecords
        ) {
            MyDrawRecordResp myDrawRecordResp = new MyDrawRecordResp();
            Integer giftId = cubeDrawRecord.getGiftId();
            Gift gift = giftService.selectByPrimaryKey(giftId);
            String giftName = gift.getGiftName();
            String giftIcon = gift.getGiftIcon();
            myDrawRecordResp.setId(cubeDrawRecord.getId());
            myDrawRecordResp.setUserId(cubeDrawRecord.getUserId());
            myDrawRecordResp.setGiftId(giftId);
            myDrawRecordResp.setGiftName(giftName);
            myDrawRecordResp.setGiftIcon(giftIcon);
            myDrawRecordResp.setGiftNum(cubeDrawRecord.getGiftNum());
            myDrawRecordResp.setAddTime(cubeDrawRecord.getAddTime());
            myDrawRecordResp.setDrawType(cubeDrawRecord.getDrawType());
            drawRecordList.add(myDrawRecordResp);
        }*/

        return Response.ok(drawRecordList);
    }

    //获取所有中将记录
    public Response getCubeDrawRecords(int pageNum, int pageSize) {
        pageNum = (pageNum - 1) * pageSize;
        int total = cubeDrawRecordService.getCount();
        List<CubeDrawRecordForMem> records = cubeDrawRecordService.getRecords(pageNum, pageSize);
        JSONObject data = new JSONObject();
        data.put("total", total);
        data.put("records", records);
        return Response.ok(data);
    }

    //获取中奖排行榜
    @SneakyThrows
    public Response getDrawRange() {
        String drawRangeRedisKey = RoomUtils.getDrawRangeRedisKey();

        if (!redisUtils.hasKey(drawRangeRedisKey)) {
            Thread.sleep(3000);
            if (!redisUtils.hasKey(drawRangeRedisKey)) {
                return Response.error(ErrorCode.SERVER_BUSY, "服务器繁忙，请稍后再试");
            }
        }
        List list = redisUtils.list_range(drawRangeRedisKey);
        List<CubeDrawRange> data = new ArrayList<>();
        for (Object resultString : list
        ) {
            CubeDrawRange cubeDrawRange = JSONObject
                .parseObject(resultString.toString(), CubeDrawRange.class);
            data.add(cubeDrawRange);
        }
        //排行取前十个
        if (data.size() > 10) {
            data = data.subList(0, 10);
        }
        return Response.ok(data);
    }

    public int getPrizeIndex(List<Cube> cubes) {
        int random = -1;
        try {
            //计算总权重
            double sumWeight = 0;
            for (Cube cube : cubes) {
                sumWeight += cube.getOdds();
            }

            //产生随机数
            double randomNumber;
            randomNumber = Math.random();

            //根据随机数在所有奖品分布的区域并确定所抽奖品
            double d1 = 0;
            double d2 = 0;
            for (int i = 0; i < cubes.size(); i++) {
                d2 += Double.parseDouble(String.valueOf(cubes.get(i).getOdds())) / sumWeight;
                if (i == 0) {
                    d1 = 0;
                } else {
                    d1 +=
                        Double.parseDouble(String.valueOf(cubes.get(i - 1).getOdds())) / sumWeight;
                }
                if (randomNumber >= d1 && randomNumber <= d2) {
                    random = i;
                    break;
                }
            }
        } catch (Exception e) {
            log.error("生成抽奖随机数出错，出错原因：{}", e.getMessage());
        }
        return random;
    }

    public List<Gift> getBaodengGift(String type) {
        List<Cube> cubes = cubeService.selectByType(type);
        List<Gift> baodengGifts = new ArrayList<>();
        for (Cube cube : cubes
        ) {
            if (cube.getIsBaodeng() == 1) {
                baodengGifts.add(giftService.selectByPrimaryKey(cube.getGiftId()));
            }
        }
        return baodengGifts;
    }

    public BaodengGiftInfo getBaodengInfo(List<Gift> baodengGifts) {
        List<BaodengGiftInfo> baodengInfos = new ArrayList<>();
        BaodengGiftInfo baodengGiftInfo = new BaodengGiftInfo();
        int index = 0;
        for (int i = 0; i < baodengGifts.size(); i++) {
            if (baodengGifts.get(i).getNeedCoin() > baodengGifts.get(index).getNeedCoin()) {
                index = i;
            }
        }
        baodengGiftInfo.setGiftIcon(baodengGifts.get(index).getGiftIcon());
        baodengGiftInfo.setOdds(getRandomOdds());
        return baodengGiftInfo;
    }

    public double getRandomOdds() {
        double[] doubles = new double[]{1.5, 2.5, 3.5, 4.5};
        int i = new Random().nextInt(3);
        return doubles[i];
    }

}
